Skip to content

Conversation

@mstoeckl
Copy link
Contributor

@mstoeckl mstoeckl commented Dec 7, 2025

  • Added a CHANGELOG.md entry

Summary

This fixes a panic that can occur when the parameter n for the Binomial sampler is larger than i64::MAX.

Motivation

This should resolve #21 .

Details

The key variable which previously used i64 in binomial::btpe was y, the random coordinate in 0..=n on which the BTPE algorithm performed rejection sampling. Since n is in 0..u64::MAX, y should also be in u64::MAX.

This is a value-breaking change, because e.g. the code now does the float->int cast on the value x_l + v.ln() / lambda_l after checking whether the value is <= 0, instead of before. I don't think this sort of change in boundary rounding should cause any issues (and it may make the sampled distribution closer to the actual target.) I am looking into writing a test to confirm this is OK, but it may be a few weeks before it is ready. (Tested, the new version actually fixes a boundary issue, see test for it in #47.)

@mstoeckl mstoeckl force-pushed the binomial-u64 branch 2 times, most recently from d908a79 to 3904835 Compare December 7, 2025 17:39
Copy link
Member

@benjamin-lieser benjamin-lieser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you a lot, this looks good.

@benjamin-lieser
Copy link
Member

You say that even the low significant bits are now correctly distributed. Should we remove the disclaimer from the documentation?

@mstoeckl
Copy link
Contributor Author

mstoeckl commented Dec 15, 2025

You say that even the low significant bits are now correctly distributed.

No, #47 only checks that the least significant bit is correctly distributed for n below 2^53, as it was before; above 2^53, the following warning remains accurate.

/// The implementation uses `f64` internally, which leads to rounding errors for big numbers.
/// For very large samples (`> 2^53`) the least significant bits of the output will not be random.
/// This means that something like `bin.sample(&mut rand::rng()) % 4` will not follow the correct distribution.
/// The more significant bits should be correctly distributed.

@benjamin-lieser benjamin-lieser merged commit bfcb948 into rust-random:master Dec 15, 2025
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Panic in Binomial::sample with small p and n close to u64::MAX

2 participants